package com.fw4j.jdbc.dao;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fw4j.jdbc.annotation.Column;
import com.fw4j.jdbc.annotation.Entity;
import com.fw4j.jdbc.annotation.Key;
import com.fw4j.jdbc.annotation.Table;
import com.fw4j.jdbc.engine.Operate;
import com.fw4j.jdbc.engine.TransactionCallback;
import com.fw4j.jdbc.exception.InstanceException;

/**
 * @author 穆仁超
 * 数据库操作类
 * 日期 2013-12-27 16:34
 * 我的QQ群：32894018
 */
public abstract class DaoTemplate{
	
	protected static Logger logger = LoggerFactory.getLogger(BaseDao.class);
	protected List<Object> paramsList = null;
	protected String sql = null;
	protected Class<?> cl = null;
	protected java.sql.Connection conn = null;
	
	public void setConnection(java.sql.Connection conn){
		this.conn = conn;
	}
	
	public int saveOrUpdate(Object obj) throws SQLException, InstanceException{
		if(cl == null){
			throw new InstanceException("Class is not undefined");
		}
		Annotation[] et = cl.getAnnotations();
		Table tb = null;
		boolean isEntity = false;
		for(Annotation t : et){
			if(t instanceof Table){
				tb = (Table)t;
			}else if(t instanceof Entity){
				isEntity = true;
			}//end if
		}//end if
		if(tb != null && isEntity){
			String tablename = tb.value();
			String keyId = null;
			Object keyValue = null;
			Method[] ms = cl.getMethods();
			Collection<String> columnList = new ArrayList<String>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ();
			paramsList = new ArrayList<Object>();
			for(Method m : ms){
				Annotation[] ans = m.getAnnotations();
				StringBuffer methodName = new StringBuffer(m.getName());
				String getMethod = methodName.toString().startsWith("get")?methodName.toString():
				methodName.replace(0, 3, "get").toString();
				boolean isKey = false;
				try{
					for(Annotation a : ans){
						if(a instanceof Key){
							isKey = true;
						}else if(a instanceof Column){
							Column id = (Column)a;
							if(isKey){
								keyId = id.value();
								keyValue = cl.getMethod(getMethod.toString(),null).invoke(obj, null);
								isKey = false;
							}else{
								columnList.add(id.value());
								paramsList.add(cl.getMethod(getMethod.toString(),null).invoke(obj, null));
							}//end if
						}//end if
					}//end for
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}//end for
			//数据库操作
			Operate op = new Operate(conn);
			StringBuffer sb = new StringBuffer();
			if(keyValue != null && Integer.parseInt(keyValue.toString()) > 0){
				paramsList.add(keyValue);
				sb.append("update ");
				sb.append(tablename);
				sb.append(" set ");
				for(String column : columnList){
					sb.append(column);
					sb.append("=?,");
				}
				sb.replace(sb.length()-1, sb.length(), " where ");
				sb.append(keyId);
				sb.append("=?");
				op.modify(sb.toString(), paramsList.toArray());
			}else if(columnList != null && columnList.size()>0){
				sb.append("insert into ");
				sb.append(tablename);
				sb.append("(");
				for(String column : columnList){
					sb.append(column);
					sb.append(",");
				}
				sb.replace(sb.length()-1, sb.length(), ") ");
				sb.append(" values(");
				for(String column : columnList){
					sb.append("?,");
				}
				sb.replace(sb.length()-1, sb.length(), ")");
				op.modify(sb.toString(), paramsList.toArray());
			}//end if
		}//end if
		return 0;
	}

	public Object getAll()  throws SQLException, InstanceException{
		if(cl == null){
			throw new InstanceException("Class is not undefined");
		}
		String tablename = null;
		Annotation[] et = cl.getAnnotations();
		Table tb = null;
		for(Annotation t : et){
			if(t instanceof Table){
				tb = (Table)t;
				tablename = tb.value();
			}//end if
		}//end if
		if(tb!=null){
			String sql = "select * from "+tablename;
			try {
				return new Operate(conn).query(cl, sql, null);
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}//end if
		return null;
	}
	
	protected Object fw4j_dao_find(String sql,List<?> params) throws SQLException{
		Annotation[] et = cl.getAnnotations();
		boolean isTable = false;
		boolean isEntity = false;
		for(Annotation t : et){
			if(t instanceof Table){
				isTable = true;
			}else if(t instanceof Entity){
				isEntity = true;
			}//end if
		}//end if
		if(isTable && isEntity){
			try {
				return new Operate(conn).query(cl, sql, params.toArray());
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}else{
			logger.error("Class "+cl.getName()+"no Annotation Entity or Table");
		}//end if
		return null;
	}
	
	protected Integer fw4j_dao_modify(String sql,List<?> params) throws SQLException{
		Annotation[] et = cl.getAnnotations();
		boolean isTable = false;
		boolean isEntity = false;
		for(Annotation t : et){
			if(t instanceof Table){
				isTable = true;
			}else if(t instanceof Entity){
				isEntity = true;
			}//end if
		}//end if
		if(isTable && isEntity){
			return new Operate(conn).modify(sql, params.toArray());
		}else{
			logger.error("Class "+cl.getName()+"no Annotation Entity or Table");
		}//end if
		return -1;
	}
}
